home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
176-200
/
disk_195
/
microemacs
/
src.zoo
/
st520.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-23
|
22KB
|
933 lines
/* ST520: Atari ST1040/520 support functions
written by lots of people (see below)
Daniel Lawrence
James Turner
Jeff Lomicka
J. C. Benoist
Modification History:
31-dec-87 Jeff Lomicka
- massive changes/additions for accessories and mouse
20-jan-87 Daniel Lawrence
- changed code in domousekey() to pass five bytes, two zeros
(to tell input.c that this is a mouse event), x/ypos
and the mouse event type.
may 88 Jeff Lomicka and Dan Lawrence
- a lot of changes. Through out aline.h, use the MWC and
ATARI names for things now.
- moving the mouse to the extreme upper left brings up
the desk accessory menu. EMACS won't replot on the
way out yet.
- cleaned up behavior of the mouse and the cursor on exit
26-feb-89 Daniel Lawrence
- rewote input layer to conform to new specs in input.c
*/
#define termdef 1 /* don't define "term" external */
#include <stdio.h>
#include "estruct.h"
#include "etype.h"
#include "edef.h"
#include "elang.h"
#if ATARI & ST520
/*
These routines provide support for the ATARI 1040ST and 520ST
using the virtual VT52 Emulator
*/
#include <aesbind.h>
#include <gemdefs.h>
#include <obdefs.h>
#include <osbind.h>
#include <xbios.h>
#include <linea.h>
#define NROW 50 /* Screen size. */
#define NCOL 80 /* Edit if you want to. */
#define MARGIN 8 /* size of minimim margin and */
#define SCRSIZ 64 /* scroll size for extended lines */
#define NPAUSE 300 /* # times thru update to pause */
#define BIAS 0x20 /* Origin 0 coordinate bias. */
#define ESC 0x1B /* ESC character. */
#define SCRFONT 2 /* index of 8x16 monochrome system default font */
#define DENSIZE 50 /* # of lines in a dense screen */
/**** ST Internals definitions *****/
/* BIOS calls */
#define BCONSTAT 1 /* return input device status */
#define CONIN 2 /* read character from device */
#define BCONOUT 3 /* write character to device */
/* XBIOS calls */
#define INITMOUS 0 /* initialize the mouse */
#define GETREZ 4 /* get current resolution */
#define SETSCREEN 5 /* set screen resolution */
#define SETPALETTE 6 /* set the color pallette */
#define SETCOLOR 7 /* set or read a color */
#define CURSCONF 21 /* set cursor configuration */
#define IKBDWS 25 /* intelligent keyboard send command */
#define KBDVBASE 34 /* get keyboard table base */
/* GEMDOS calls */
#define EXEC 0x4b /* Exec off a process */
#define CON 2 /* CON: Keyboard and screen device */
/* Palette color definitions */
#define LOWPAL "000700070770007707077777333733373773337737377777"
#define MEDPAL "000700007777"
#define HIGHPAL "111000"
/* ST Global definitions */
int initrez; /* initial screen resolution */
int currez; /* current screen resolution */
int gemflag; /* were we called from the desktop? */
int mouseon; /* True if mouse is on */
char resname[][8] = { /* screen resolution names */
"LOW", "MEDIUM", "HIGH", "DENSE"
};
short spalette[16]; /* original color palette settings */
short palette[16]; /* current palette settings */
static short scursor; /* original text cursor mode */
struct la_data *aline; /* Line A data structure */
struct la_ext *naline; /* extended Line A data structure */
struct la_font **fonts; /* Array of pointers to the three system
font headers returned by init (in register A1) */
struct la_font *system_font; /* pointer to default system font */
struct la_font *small_font; /* pointer to small font */
/*
These are needed to make GEM happy
*/
int contrl[ 11], intin[ 128], intout[ 128], ptsin[ 256], ptsout[ 12];
static int worki[ 11] = {1,1,1,1,1,1,1,1,1,1,2}, worko[ 57];
/*
Some useful information about our environment
*/
static int
g_wchar, g_hchar, /* VDI's idea of current font size */
junk, gid, wkid; /* Graphics ID, workstation ID */
static int oldbut = 0; /* Previous state of mouse buttons */
static int mctrl; /* current BEG_MOUSE state */
/*
This object tree is for displaying the desk accessory menu.
Actual positions are written into this structure when the
screen size is known.
*/
OBJECT menu[] =
{
-1, 1, 4, G_IBOX, NONE, NORMAL, 0x0L, 0 , 0, 0, 0,/* Root */
4, 2, 2, G_BOX, NONE, NORMAL, 0x10F0L, 0, 0, 1, 1,/* BAR */
1, 3, 3, G_IBOX, NONE, NORMAL, 0x0L, 0, 0, 1, 1,/* Active */
2,-1,-1, G_TITLE, NONE, NORMAL, "", 0, 0, 1, 1,/* title */
0, 5, 5, G_IBOX, NONE, NORMAL, 0x0L, 0, 0, 0, 0,/* screen */
4, 6,13, G_BOX, NONE, NORMAL, 0xFF1100L, 0, 0, 0, 0,/* box */
7,-1,-1, G_STRING, NONE, NORMAL, TEXT179,0,0,168, 16,
/* " About MicroEmacs" */
8,-1,-1, G_STRING, NONE,DISABLED, "---------------------",
0, 16, 168, 16,
9,-1,-1, G_STRING, NONE, NORMAL, "", 0, 32, 168, 16,
10,-1,-1, G_STRING, NONE, NORMAL, "", 0, 48, 168, 16,
11,-1,-1, G_STRING, NONE, NORMAL, "", 0, 64, 168, 16,
12,-1,-1, G_STRING, NONE, NORMAL, "", 0, 80, 168, 16,
13,-1,-1, G_STRING, NONE, NORMAL, "", 0, 96, 168, 16,
5,-1,-1, G_STRING, LASTOB, NORMAL, "", 0,112, 168, 16
};
extern mymouse(); /* .s file for calling two mouse handlers */
int (*first_mhandler)(); /* Address of first handler */
int (*second_mhandler)(); /* Address of second handler */
struct kbdvbase *kv; /* Keyboard vector table */
static int msevntsiz = 0; /* Events in private mouse event queue */
static unsigned short msevntq[16];/* State of mouse keys at event */
static int msevntin = 0; /* Queue input ptr */
static int msevntout = 0; /* Queue output ptr */
static int mousekeys1 = 0; /* Last mouse key event */
static int mousecol = HUGE; /* current mouse column */
static int mouserow = HUGE; /* current mouse row */
extern int ttopen(); /* Forward references. */
extern int ttgetc();
extern int ttputc();
extern int ttflush();
extern int ttclose();
extern int stmove();
extern int steeol();
extern int steeop();
extern int stbeep();
extern int stopen();
extern int stclose();
extern int stgetc();
extern int stputc();
extern int strev();
extern int strez();
extern int stkopen();
extern int stkclose();
#if COLOR
extern int stfcol();
extern int stbcol();
#endif
/*
* Dispatch table. All the
* hard fields just point into the
* terminal I/O code.
*/
TERM term = {
NROW-1,
NROW-1,
NCOL,
NCOL,
MARGIN,
SCRSIZ,
NPAUSE,
&stopen,
&stclose,
&stkopen,
&stkclose,
&stgetc,
&stputc,
&ttflush,
&stmove,
&steeol,
&steeop,
&stbeep,
&strev,
&strez
#if COLOR
, &stfcol,
&stbcol
#endif
};
/* input buffers and pointers */
#define IBUFSIZE 64 /* this must be a power of 2 */
unsigned char in_buf[IBUFSIZE]; /* input character buffer */
int in_next = 0; /* pos to retrieve next input character */
int in_last = 0; /* pos to place most recent input character */
in_init() /* initialize the input buffer */
{
in_next = in_last = 0;
}
in_check() /* is the input buffer non-empty? */
{
if (in_next == in_last)
return(FALSE);
else
return(TRUE);
}
in_put(event)
int event; /* event to enter into the input buffer */
{
in_buf[in_last++] = event;
in_last &= (IBUFSIZE - 1);
}
int in_get() /* get an event from the input buffer */
{
register int event; /* event to return */
event = in_buf[in_next++];
in_next &= (IBUFSIZE - 1);
return(event);
}
void init_aline()
{
int *ld_contrl;
int *ld_intin;
linea0();
/* save if the current mouse is hidden (ie we are not in GEM) */
gemflag = (mousehidden == 0);
while (mousehidden) {
showmouse();
}
aline = (struct la_data *)(la_init.li_a0);
fonts = (struct la_font **)(la_init.li_a1);
naline = ((struct la_ext *)aline) - 1;
scursor = naline->ld_status; /* State of text cursor */
ld_contrl = aline->ld_contrl; /* -> control junk */
ld_intin = aline->ld_intin; /* -> intin junk */
}
init()
{
init_aline();
system_font = fonts[SCRFONT]; /* save it */
small_font = fonts[1];
}
switch_font(fp)
struct la_font *fp;
{
/* See linea.h for description of fields */
V_CEL_HT = fp->font_height;
V_CEL_WR = aline->ld_vwrap * fp->font_height;
V_CEL_MY = (naline->ld_y_max / fp->font_height) - 1;
V_CEL_MX = (naline->ld_x_max / fp->font_fat_cell) - 1;
V_FNT_WR = fp->font_width;
V_FNT_ST = fp->font_low_ade;
V_FNT_ND = fp->font_hi_ade;
V_OFF_AD = (long) fp->font_char_off;
V_FNT_AD = (long) fp->font_data;
}
stmove(row, col)
{
stputc(ESC);
stputc('Y');
stputc(row+BIAS);
stputc(col+BIAS);
}
steeol()
{
stputc(ESC);
stputc('K');
}
steeop()
{
#if COLOR
stfcol(gfcolor);
stbcol(gbcolor);
#endif
stputc(ESC);
stputc('J');
}
strev(status) /* set the reverse video state */
int status; /* TRUE = reverse video, FALSE = normal video */
{
if (currez > 1) {
stputc(ESC);
stputc(status ? 'p' : 'q');
}
}
#if COLOR
mapcol(clr) /* medium rez color translation */
int clr; /* emacs color number to translate */
{
static int mctable[] = {0, 1, 2, 3, 2, 1, 2, 3};
if (currez != 1)
return(clr);
else
return(mctable[clr]);
}
stfcol(color) /* set the forground color */
int color; /* color to set forground to */
{
if (currez < 2) {
stputc(ESC);
stputc('b');
stputc(mapcol(color));
}
}
stbcol(color) /* set the background color */
int color; /* color to set background to */
{
if (currez < 2) {
stputc(ESC);
stputc('c');
stputc(mapcol(color));
}
}
#endif
static char beep[] = {
0x00, 0x00,
0x01, 0x01,
0x02, 0x01,
0x03, 0x01,
0x04, 0x02,
0x05, 0x01,
0x07, 0x38,
0x08, 0x10,
0x09, 0x10,
0x0A, 0x10,
0x0B, 0x00,
0x0C, 0x30,
0x0D, 0x03,
0xFF, 100,
0x09, 0x00,
0x0A, 0x00,
0xFF, 0x00
};
stbeep()
{
Dosound(beep);
}
mouse_on() /* turn the gem mouse ON */
{
if (!mouseon) {
graf_mouse( M_ON, 0L);
graf_mouse(ARROW, 0L);
mouseon = 1;
}
}
mouse_off() /* turn the gem mouse OFF */
{
if (mouseon) {
graf_mouse( M_OFF, 0L);
mouseon = 0;
}
if( !mousehidden) stbeep();
}
/*
me_mh - MicroEmacs Mouse interrupt Handler. This handler is called,
in addition to the regular mouse handler, in order for microemacs
to have access to some more information about the mouse events.
What it does is:
- Queue a copy of the mouse button state at the actual moment of
the event, rather than after GEM is finished playing with timers.
- Convert all right-mouse-button events into left-mouse-button
events BEFORE GEM's mouse interrupt handler, so that GEM will generate
a left-mouse-button event.
*/
me_mh(a)
char *a;
{
register unsigned mousekeys;
mousekeys = a[0] & 7;
if (mousekeys != 0)
a[0] = 0xFA; /* Any key down means button 1 down */
else
a[0] = 0xf8; /* Otherwise button 1 up */
if (msevntsiz < 16) {
/* Previous event was processed, look for next one */
if (mousekeys != mousekeys1) {
/* A button change is detected, insert it in queue */
msevntq[msevntin++] = mousekeys;
msevntin &= 15;
msevntsiz++;
mousekeys1 = mousekeys;
}
}
}
stkopen() /* open the keyboard (and mouse) */
{
}
stopen() /* open the screen */
{
register int i;
init();
/*
Set up an interrupt handler for the mouse that performs both
me_mh() and the default mouse handling. The .s file "stmouse.s"
contains some special code for this purpose.
*/
first_mhandler = me_mh;
kv = Kbdvbase();
second_mhandler = kv->kb_mousevec;
kv->kb_mousevec = mymouse;
/*
In order to have both the mouse cursor and the text cursor on the
screen at the same time, we have to flash it ourselves, turning
the mouse cursor on and off for each flash.
The cursors are both off whenever we are not in an input wait.
*/
Cursconf(3, 0); /* Stop text cursor from flashing */
Cursconf(0, 0); /* Turn text cursor off */
/*
Wake up GEM and the VDI
*/
appl_init();
gid = graf_handle(&g_wchar, &g_hchar, &junk, &junk);
#if 0
/* We never use the VDI, but if you do, turn this back on */
v_opnvwk(worki, &wkid, worko);
#endif
graf_mouse( M_OFF, 0L);
mouseon = 0;
/*
Set up the menu bar's coordinates to match the font and screen size
for this screen resolution
*/
wind_get(0, WF_CURRXYWH, /* Fetch actual screen size for menu */
&menu[0].ob_x, &menu[0].ob_y,
&menu[0].ob_width, &menu[0].ob_height);
menu[1].ob_x = menu[0].ob_width - 1; /* Locate "desk" box */
menu[4].ob_width = menu[0].ob_width;
menu[4].ob_height = 8*g_hchar;
menu[5].ob_width = 21*g_wchar;
menu[5].ob_height = 8*g_hchar;
menu[5].ob_x = menu[0].ob_width - menu[5].ob_width;
for(i=6; i<14; i++) {
/* Desk accessory items */
menu[i].ob_y = (i-6)*g_hchar;
menu[i].ob_width = menu[5].ob_width;
menu[i].ob_height = g_hchar;
}
menu_bar(menu, 1);
/*
Shut off GEM's user interface until we enter an input wait.
Note that unless we claim the mouse with BEG_MCTRL, we will not
get scheduled to run any time the left mouse button goes down while
the mouse is on the top 16 pixels of the screen. We keep Emacs
"hung" whenever MCTRL is given to desk accessories or GEM, and keep
GEM hung whenever we have control.
*/
wind_update(BEG_UPDATE); /* Shuts off GEM drawing */
wind_update(BEG_MCTRL); /* Shuts off GEM use of mouse */
mctrl = 0; /* Flag that we have mouse control */
ttopen();
eolexist = TRUE;
/* save the current color palette */
for (i=0; i<16; i++)
spalette[i] = xbios(SETCOLOR, i, -1);
/* and find the current resolution */
initrez = currez = xbios(GETREZ);
strcpy(sres, resname[currez]);
/* set up the screen size and palette */
switch (currez) {
case 0: term.t_mrow = 25 - 1;
term.t_nrow = 25 - 1;
term.t_ncol = 40;
strcpy(palstr, LOWPAL);
break;
case 1: term.t_mrow = 25 - 1;
term.t_nrow = 25 - 1;
strcpy(palstr, MEDPAL);
break;
case 2: term.t_mrow = DENSIZE - 1;
term.t_nrow = 25 - 1;
strcpy(palstr, HIGHPAL);
}
/* and set up the default palette */
spal(palstr);
stputc(ESC); /* automatic overflow off */
stputc('w');
/* initialize the input buffer */
in_init();
}
stkclose() /* close the keyboard (and mouse) */
{
}
stclose()
{
stputc(ESC); /* auto overflow on */
stputc('v');
/* restore the original screen resolution */
if (currez == 3)
switch_font(system_font);
strez(resname[initrez]);
/* restore the original palette settings */
xbios(SETPALETTE, spalette);
ttclose();
kv->kb_mousevec = second_mhandler; /* Restore original handler */
mouse_on(); /* turn the mouse on */
if (gemflag != 0) {
/* coming from gem..... we */
Cursconf(0, 0); /* turn the cursor off */
} else {
/* coming from a shell, we */
Cursconf(1, 0); /* turn the cursor on */
Cursconf(2, 0); /* Turn text cursor blinking */
hidemouse(); /* Turn mouse off for shell */
}
wind_update(END_MCTRL); /* Return GEM's control of screen */
wind_update(END_UPDATE);
#if 0
v_clsvwk(wkid); /* Clean up GEM */
#endif
appl_exit();
}
/* spal(pstr): reset the current palette according to a
"palette string" of the form
000111222333444555666777
which contains the octal values for the palette registers
*/
spal(pstr)
char *pstr; /* palette string */
{
int pal; /* current palette position */
int clr; /* current color value */
int i;
for (pal = 0; pal < 16; pal++) {
if (*pstr== 0)
break;
/* parse off a color */
clr = 0;
for (i = 0; i < 3; i++)
if (*pstr)
clr = clr * 16 + (*pstr++ - '0');
palette[pal] = clr;
};
/* and now set it */
xbios(SETPALETTE, palette);
}
static domousekey(newbut, sk)
int sk;
{
register int k;
for(k=1; k!=4; k = k<<1) { /* J is butnum, k is bit num */
/* For each button on the mouse */
if ((oldbut&k) != (newbut&k)) {
/* This button changed, generate an event */
in_put(0); /* escape indicator */
in_put(MOUS >> 8); /* mouse event */
in_put(mousecol); /* x-position */
in_put(mouserow); /* y-position */
in_put(((newbut&k) ? 0 : 1)
+ (k==1 ? 4 : 0)
+ ((sk&3) ? 'A' : 'a'));
}
}
oldbut = newbut;
}
stgetc() /* get a char from the keyboard */
{
register int flashcounter; /* Counter for flashing cursor */
register int ev_which; /* Event returned */
register int sc; /* Keyboard scan code */
static int bexpected = 1; /* Expected next mouse state */
int mx, my, bstate, sk, key, mc;/* Event parameters */
int mes[8];
/* Working out a multi-byte input sequence */
if (in_check())
return(in_get());
Cursconf(1, 0); /* Turn text cursor on */
mouse_on(); /* Let mouse work */
wind_update(END_UPDATE);
if (mctrl)
wind_update(END_MCTRL);
flashcounter = 0;
for(;;) {
if (!mctrl) {
/* We have control, so it is okay to flash cursor */
if (flashcounter == 6) {
mouse_off();
Cursconf(0, 0); /* After 60ms, turn it off */
mouse_on();
} else if (flashcounter == 10) {
/* Wrapped around one cycle of cursor flashing,
turn it on */
mouse_off();
Cursconf(1, 0);
mouse_on();
flashcounter = 0;
}
}
/* do the event-multi thing */
ev_which = evnt_multi(
MU_TIMER | MU_MESAG | MU_KEYBD | MU_BUTTON | MU_M1,
1, /* Maximum clicks to wait for */
1, /* Buttons that generate events */
bexpected, /* Button states that generate events */
0, menu[1].ob_x, menu[1].ob_y,
menu[1].ob_width, menu[1].ob_height,
0, 0, 0, 0, 0, /* enter/exit, x, y, w, h for rect 2 */
mes, /* Buffer to receive mesasge */
/* Low and high order miliseconds of counter */
100, 0,
&mx, &my, /* Mouse location */
&bstate, /* State of the mouse buttons */
&sk, /* State of the shift keys */
&key, /* Key pressed */
&mc); /* Actual number of clicks */
if (ev_which & MU_KEYBD) {
/* Keyboard events cause keystrokes, add SPC prefix to fn keys */
if (mctrl)
wind_update(BEG_MCTRL);
Giaccess(0, 9+128);
Giaccess(0, 10+128);
/* Cancel any double-clicking */
nclicks = 0;
mctrl = 0;
sc = key>>8;
key &= 0xff;
/* a keycode of 0 indicates an extended char code */
if (key == 0) {
key = extcode(sc);
in_put(0); /* escape indicator */
in_put(key >> 8);/* key type */
in_put(key & 255);/* key code */
} else {
in_put(key);
}
#if 0
if ((sc>=0x63 && sc<=0x72) || sc == 0x4a || sc == 0x4e) {
/* This is a keypad key, apply FN prefix to it */
in_put(0); /* excape indicator */
in_put(SPEC >> 8); /* function key */
in_put(key); /* code of this key */
}
#endif
} else if (ev_which & MU_BUTTON) {
/* Mouse event, look at our actual mouse event */
int top, junk;
wind_get(0, WF_TOP, &top, &junk, &junk, &junk);
if (top == 0) {
/* Desktop is top window,
allow Emacs to continue */
bexpected = (~bstate)&1;
mousecol = mx/g_wchar;
mouserow = my/g_hchar;
while(msevntsiz > 0) {
/* Process each queued event */
domousekey(msevntq[msevntout++], sk);
msevntout &= 15;
msevntsiz--;
}
if (mctrl) wind_update(BEG_MCTRL);
mctrl = 0;
}
} else if (ev_which & MU_M1) {
/* Mouse entered desk menu, allow it to appear */
if (!mctrl) wind_update(END_MCTRL);
mctrl = 1;
sgarbf = TRUE;
} else if (ev_which & MU_TIMER) {
flashcounter++;
} else {
/* Most likely is the about message */
}
/* is there now a pending event? */
if (in_check()) {
key = in_get();
break;
}
}
if (mctrl)
wind_update(BEG_MCTRL);
wind_update(BEG_UPDATE);
mouse_off();
Cursconf(0, 0); /* Turn text cursor off */
return(key & 0xFF);
}
stputc(c) /* output char c to the screen */
char c; /* character to print out */
{
bios(BCONOUT, CON, c);
}
strez(newrez) /* change screen resolution */
char *newrez; /* requested resolution */
{
int nrez; /* requested new resolution */
/* first, decode the resolution name */
for (nrez = 0; nrez < 4; nrez++)
if (strcmp(newrez, resname[nrez]) == 0)
break;
if (nrez == 4) {
mlwrite(TEXT180);
/* "%%No such resolution" */
return(FALSE);
}
/* next, make sure this resolution is legal for this monitor */
if ((currez < 2 && nrez > 1) || (currez > 1 && nrez < 2)) {
mlwrite(TEXT181);
/* "%%Resolution illegal for this monitor" */
return(FALSE);
}
/* eliminate non-changes */
if (currez == nrez)
return(TRUE);
/* finally, make the change */
switch (nrez) {
case 0: /* low resolution - 16 colors */
newwidth(TRUE, 40);
strcpy(palstr, LOWPAL);
xbios(SETSCREEN, -1L, -1L, 0);
g_wchar = g_hchar = 8;
break;
case 1: /* medium resolution - 4 colors */
newwidth(TRUE, 80);
strcpy(palstr, MEDPAL);
xbios(SETSCREEN, -1L, -1L, 1);
g_wchar = g_hchar = 8;
break;
case 2: /* High resolution - 2 colors - 25 lines */
newsize(TRUE, 25);
strcpy(palstr, HIGHPAL);
switch_font(system_font);
g_wchar = g_hchar = 16;
break;
case 3: /* Dense resolution - 2 colors - 40 lines */
newsize(TRUE, DENSIZE);
strcpy(palstr, HIGHPAL);
switch_font(small_font);
g_wchar = g_hchar = 8;
break;
}
/* and set up the default palette */
spal(palstr);
currez = nrez;
strcpy(sres, resname[currez]);
stputc(ESC); /* automatic overflow off */
stputc('w');
return(TRUE);
}
#if LATTICE
system(cmd) /* call the system to execute a new program */
char *cmd; /* command to execute */
{
char *pptr; /* pointer into program name */
char pname[NSTRING]; /* name of program to execute */
char tail[NSTRING]; /* command tail */
/* scan off program name.... */
pptr = pname;
while (*cmd && (*cmd != ' ' && *cmd != '\t'))
*pptr++ = *cmd++;
*pptr = 0;
/* create program name length/string */
tail[0] = strlen(cmd);
strcpy(&tail[1], cmd);
/* go do it! */
return(gemdos( (int)EXEC,
(int)0,
(char *)pname,
(char *)tail,
(char *)NULL));
}
#endif
#if FLABEL
fnclabel(f, n) /* label a function key */
int f,n; /* default flag, numeric argument [unused] */
{
/* on machines with no function keys...don't bother */
return(TRUE);
}
#endif
#else
sthello()
{
}
#endif